// HomeNet Devices - Simple
// 12-13-2010 <mdoll@email.usf.edu> http://opensource.org/licenses/mit-license.php
 
#ifndef HomeNetDevices_h
#define HomeNetDevices_h

#include <WProgram.h>
#include <stdint.h>

#include <../../../../libraries/Ports/Ports.h>

#include <HomeNet.h>
#include <HomeNetConfig.h>

//Arduino///////////////////////////////////////////////////////////////////////
class HomeNetDeviceArduino : public HomeNetDevice {

public:
    HomeNetDeviceArduino(HomeNet& homeNet ):HomeNetDevice(homeNet) {}
    inline uint16_t getId(){ return 0x0000; }
    HomeNetPartialPacket* process(const uint16_t& fromNode, const uint8_t& fromDevice, const uint8_t&, const HomeNetPayload&);
};
//JeeNode///////////////////////////////////////////////////////////////////////
class HomeNetDeviceJeeNode : public HomeNetDeviceArduino {

public:
    HomeNetDeviceJeeNode(HomeNet& homeNet ):HomeNetDeviceArduino(homeNet) {}
    inline uint16_t getId(){ return 0x0001; }
    HomeNetPartialPacket* process(const uint16_t& fromNode, const uint8_t& fromDevice, const uint8_t&, const HomeNetPayload&);
};

//TMP37/////////////////////////////////////////////////////////////////////////
class HomeNetDeviceTMP37 : public HomeNetDevicePort {
public:
    HomeNetDeviceTMP37(HomeNet& homeNet ):HomeNetDevicePort(homeNet) {}
    inline uint16_t getId(){ return 0x0003; }
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);

private:
    float readSensor();
};

//TMP421////////////////////////////////////////////////////////////////////////

class HomeNetDeviceTMP421 : public HomeNetDevicePortI2C {
public:
    HomeNetDeviceTMP421(HomeNet& homeNet ):HomeNetDevicePortI2C(homeNet) {}
    inline uint16_t getId(){ return 0x0004; }
    void init(uint8_t location);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);

private:
    DeviceI2C * _i2c;
    float readSensor();
};

//LDR///////////////////////////////////////////////////////////////////////////

class HomeNetDeviceLDR : public HomeNetDevicePort {
public:
    HomeNetDeviceLDR(HomeNet& homeNet ):HomeNetDevicePort(homeNet) { };
    inline uint16_t getId(){ return 0x0005; };
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
    
private:
    uint16_t readSensor();
};

//Switch////////////////////////////////////////////////////////////////////////

class HomeNetDeviceSwitch : public HomeNetDevicePort {
private:
    

public:
    HomeNetDeviceSwitch(HomeNet& homeNet ):HomeNetDevicePort(homeNet) { };
    inline uint16_t getId(){ return 0x0006; };
    void init(uint8_t location);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
    //void updateOften();


protected:
    uint8_t _state;
};

//ContactSwitch/////////////////////////////////////////////////////////////////

class HomeNetDeviceContactSwitch : public HomeNetDeviceSwitch {
public:
    HomeNetDeviceContactSwitch(HomeNet& homeNet ):HomeNetDeviceSwitch(homeNet) {};
    inline uint16_t getId(){ return 0x0007; };
    void init(uint8_t location);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
};

//LED///////////////////////////////////////////////////////////////////////////

class HomeNetDeviceLED : public HomeNetDevicePort {

public:
    HomeNetDeviceLED(HomeNet& homeNet ):HomeNetDevicePort(homeNet) {}
    inline uint16_t getId(){ return 0x0008; }
    void init(uint8_t);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
    void led(uint8_t on);

private:
   uint8_t _level;
};

//MotionSensor////////////////////////////////////////////////////////////////////////

class HomeNetDeviceMotionSensor : public HomeNetDevicePort {
public:
    HomeNetDeviceMotionSensor(HomeNet& homeNet, uint8_t timeout = 60, uint8_t trigger = RISING  ):HomeNetDevicePort(homeNet), _timeout(timeout) {
        attachInterrupt(1, onInterrupt, trigger);
    };
    inline uint16_t getId(){ return 0x0010; };
    void init(uint8_t location);
    HomeNetPartialPacket* interrupt(const uint8_t&, const HomeNetPayload&);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
    void update();

private:
    uint8_t _state;
    uint8_t _lastState;
    uint8_t _timeout;
    uint8_t _count; 
};

//SmartOutlet///////////////////////////////////////////////////////////////////

class HomeNetDeviceSmartOutlet : public HomeNetDevicePort {
public:
    HomeNetDeviceSmartOutlet(HomeNet& homeNet ):HomeNetDevicePort(homeNet) {};
    inline uint16_t getId(){ return 0; }
    void init(uint8_t location);
    HomeNetPartialPacket* process(const uint8_t&, const HomeNetPayload&);
    void outlet1(uint8_t on);
    void outlet2(uint8_t on);

private:
    boolean _state1;
    boolean _state2;
};

#endif